<?php
// +---------------------------------------------------------------------+
// | OneBase    | [ WE CAN DO IT JUST THINK ]                            |
// +---------------------------------------------------------------------+
// | Licensed   | http://www.apache.org/licenses/LICENSE-2.0 )           |
// +---------------------------------------------------------------------+
// | Author     | 王勇程 <laughskydragon@qq.com>                         |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase                      |
// +---------------------------------------------------------------------+

namespace app\common\model;

/**
 * 公告阅读记录模型
 */
class AnnouncementRead extends ModelBase
{
    // 表名

    
    // 自动时间戳
    protected $autoWriteTimestamp = 'datetime';
    
    // 时间字段
    protected $createTime = 'read_time';
    protected $updateTime = false; // 阅读记录不需要更新时间
    
    // 字段类型转换
    protected $type = [
        'id' => 'integer',
        'announcement_id' => 'integer',
        'user_id' => 'integer',
        'read_time' => 'datetime',
    ];
    
    /**
     * 标记公告为已读
     * @param int $announcementId 公告ID
     * @param int $userId 用户ID
     * @return bool
     */
    public function markAsRead($announcementId, $userId)
    {
        if ($announcementId <= 0 || $userId <= 0) {
            return false;
        }
        
        // 检查是否已经阅读过
        $exists = $this->getInfo([
            'announcement_id' => $announcementId,
            'user_id' => $userId
        ]);
        
        if (!empty($exists)) {
            return true; // 已经阅读过，直接返回成功
        }
        
        // 添加阅读记录
        $data = [
            'announcement_id' => $announcementId,
            'user_id' => $userId,
        ];
        
        return $this->setInfo($data);
    }
    
    /**
     * 批量标记公告为已读
     * @param array $announcementIds 公告ID数组
     * @param int $userId 用户ID
     * @return bool
     */
    public function markMultipleAsRead($announcementIds, $userId)
    {
        if (empty($announcementIds) || $userId <= 0) {
            return false;
        }
        
        // 获取已读的公告ID
        $readIds = $this->getColumn([
            'announcement_id' => ['in', $announcementIds],
            'user_id' => $userId
        ], 'announcement_id');
        
        // 过滤出未读的公告ID
        $unreadIds = array_diff($announcementIds, $readIds);
        
        if (empty($unreadIds)) {
            return true; // 全部已读，直接返回成功
        }
        
        // 批量插入阅读记录
        $dataList = [];
        foreach ($unreadIds as $announcementId) {
            $dataList[] = [
                'announcement_id' => $announcementId,
                'user_id' => $userId,
                'read_time' => date('Y-m-d H:i:s'),
            ];
        }
        
        return $this->setList($dataList);
    }
    
    /**
     * 检查用户是否已读某公告
     * @param int $announcementId 公告ID
     * @param int $userId 用户ID
     * @return bool
     */
    public function isRead($announcementId, $userId)
    {
        if ($announcementId <= 0 || $userId <= 0) {
            return false;
        }
        
        $info = $this->getInfo([
            'announcement_id' => $announcementId,
            'user_id' => $userId
        ]);
        
        return !empty($info);
    }
    
    /**
     * 获取用户已读的公告ID列表
     * @param int $userId 用户ID
     * @param array $announcementIds 要检查的公告ID数组，空表示所有
     * @return array
     */
    public function getUserReadAnnouncementIds($userId, $announcementIds = [])
    {
        if ($userId <= 0) {
            return [];
        }
        
        $where = ['user_id' => $userId];
        
        if (!empty($announcementIds)) {
            $where['announcement_id'] = ['in', $announcementIds];
        }
        
        return $this->getColumn($where, 'announcement_id');
    }
    
    /**
     * 获取公告的阅读统计
     * @param int $announcementId 公告ID，0表示所有公告
     * @param string $startDate 开始日期
     * @param string $endDate 结束日期
     * @return array
     */
    public function getReadStatistics($announcementId = 0, $startDate = '', $endDate = '')
    {
        $where = [];
        
        // 添加公告ID条件
        if ($announcementId > 0) {
            $where['announcement_id'] = $announcementId;
        }
        
        // 添加日期范围条件
        if (!empty($startDate)) {
            $where[] = ['read_time', '>=', $startDate . ' 00:00:00'];
        }
        if (!empty($endDate)) {
            $where[] = ['read_time', '<=', $endDate . ' 23:59:59'];
        }
        
        return [
            'total_read_count' => $this->stat($where, 'count'),
            'unique_user_count' => $this->stat($where, 'count', 'DISTINCT user_id'),
        ];
    }
    
    /**
     * 获取热门公告排行（按阅读量）
     * @param int $limit 限制数量
     * @param string $startDate 开始日期
     * @param string $endDate 结束日期
     * @return array
     */
    public function getHotAnnouncements($limit = 10, $startDate = '', $endDate = '')
    {
        $where = [];
        
        // 添加日期范围条件
        if (!empty($startDate)) {
            $where[] = ['read_time', '>=', $startDate . ' 00:00:00'];
        }
        if (!empty($endDate)) {
            $where[] = ['read_time', '<=', $endDate . ' 23:59:59'];
        }
        
        // 使用原生SQL查询统计
        $whereStr = empty($where) ? '1=1' : $this->parseWhere($where);
        $sql = "SELECT announcement_id, COUNT(*) as read_count, COUNT(DISTINCT user_id) as unique_user_count 
                FROM {$this->getTable()} 
                WHERE {$whereStr} 
                GROUP BY announcement_id 
                ORDER BY read_count DESC 
                LIMIT {$limit}";
        
        return $this->dbQuery($sql);
    }
    
    /**
     * 获取用户阅读历史
     * @param int $userId 用户ID
     * @param int $limit 限制数量
     * @param int $page 页码
     * @return array
     */
    public function getUserReadHistory($userId, $limit = 20, $page = 1)
    {
        if ($userId <= 0) {
            return [];
        }
        
        $where = ['user_id' => $userId];
        $field = 'announcement_id,read_time';
        $order = 'read_time DESC';
        $paginate = ['list_rows' => $limit, 'page' => $page];
        
        return $this->getList($where, $field, $order, $paginate);
    }
    
    /**
     * 清理过期阅读记录
     * @param int $days 保留天数，默认365天
     * @return bool
     */
    public function cleanExpiredRecords($days = 365)
    {
        $expireDate = date('Y-m-d H:i:s', time() - $days * 86400);
        $where = [['read_time', '<', $expireDate]];
        
        return $this->deleteInfo($where, true);
    }
}